﻿/*
* This file is part of WinMergeFS.
*
* WinMergeFS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.

* WinMergeFS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WinMergeFS.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Data;
using WinMergeFS.Common;
using WinMergeFS.API;

namespace WinMergeFS.W32
{
    static class Program
    {
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        static void Main(string[] args)
        {
            // this the case when the user calls the exe file
            if (Environment.UserInteractive)
            {

                // enable CTRL-C trapping
                ConsoleKeyInfo cki;
                Console.TreatControlCAsInput = true;

                //Show copyright information
                Console.WriteLine("WinMergeFS - (C) 2009-2010 m0viefreak & Duke\n");

                // retrieve command line arguments as a CommandLineArguemts object
                CommandLineArguments cmdline = new CommandLineArguments(args);


                // create a list of known parameters to react on invalid userinput
                List<string> knownparameters = new List<string>();

                knownparameters.Add("sample");
                knownparameters.Add("debug-service");
                knownparameters.Add("install-service");
                knownparameters.Add("remove-service");
                knownparameters.Add("version");
                knownparameters.Add("profile");
                knownparameters.Add("logfile");
                knownparameters.Add("loglevel");
                knownparameters.Add("volumeid");
                knownparameters.Add("create-profile");
                knownparameters.Add("driveletter");
                knownparameters.Add("manual");
                knownparameters.Add("plugins");
                knownparameters.Add("roots");
                knownparameters.Add("rroots");

                // make sure all parameters are recognized
                for (int i = 0; i < cmdline.Switches.Count; i++)
                {
                    if (!knownparameters.Contains(cmdline.Switches[i]))
                    {
                        Console.Error.WriteLine("Invalid parameter \"" + cmdline.Switches[i] + "\".\nCall WinMergeFS without parameters for a list of options");
                        return;
                    }
                }

                // set mounter to null (needed for check if mounted, later)
                Mounter mounter = null;


                // parse cmdline arguments
                if (cmdline["sample"] != null && cmdline["sample"] != "true")
                {
                    CreateSampleConfig(cmdline["sample"]);
                    Console.WriteLine("Sample config created.");
                    Console.WriteLine("Edit the file, rename it to \"config.xml\", and place it next to this application.");
                    return;
                }

                else if (cmdline["debug-service"] != null)
                {
                    // debug stuff, run service as normal application to simplify debugging
                    mounter = new Mounter();
                    if (!mounter.mountService(cmdline)) return;
                }

                else if (cmdline["install-service"] != null)
                {
                    string path = System.IO.Path.GetFullPath(System.Reflection.Assembly.GetEntryAssembly().Location);
                    System.Diagnostics.Process.Start("sc", "create WMFSsvc binPath= \"" + path + "\"");
                    Console.WriteLine("Installing service.");
                    return;
                }

                else if (cmdline["remove-service"] != null)
                {
                    System.Diagnostics.Process.Start("sc", "delete WMFSsvc");
                    Console.WriteLine("Removing service.");
                    return;
                }

                else if (cmdline["version"] != null)
                {
                    string SVCversion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
                    string APIversion = WinMergeFS.API.WinMergeFS.Version;
                    Console.WriteLine("WinMergeFS Version " + SVCversion);
                    Console.WriteLine("WinMergeFS-API Version " + APIversion);
                    return;
                }


                else if (cmdline["profile"] != null && cmdline["profile"] != "true")
                {
                    mounter = new Mounter();
                    if (!mounter.mountProfile(cmdline)) return;
                }


                else if (cmdline["manual"] != null && cmdline["manual"] == "true")
                {
                    mounter = new Mounter();
                    if (!mounter.mountManual(cmdline)) return;
                }

                else if (cmdline["create-profile"] != null && cmdline["create-profile"] != "true")
                {
                    mounter = new Mounter();
                    Profile newprofile = mounter.createProfile(cmdline);
                    if (newprofile != null)
                    {
                        if (WinMergeFS.API.ProfileManager.SaveProfileToFile(newprofile, cmdline["create-profile"])) 
                            Console.Write("Profile saved to " + cmdline["create-profile"]);
                    }
                    return;
                }

                else
                {
                    // console width:  80!
                    //string exename = "WinMergeFS";
                    //Console.WriteLine("\nUsage: " + exename + " <parameters>\n\nParameters:");
                    //Console.WriteLine("  -manual                             manual mount, expects -roots or -rroots");
                    //Console.WriteLine("                                      and -driveletter");
                    //Console.WriteLine("  -profile <filename.xml>             mount the specified profile");
                    //Console.WriteLine("  -create-profile <filename.xml>      create a profile, -roots, -driveletter ...");
                    //Console.WriteLine("");
                    //Console.WriteLine("  -roots <root1>::<root2>::...        roots, separate by \"::\"");
                    //Console.WriteLine("  -rroots <root1>::<root2>::...       like -roots, but read only");
                    //Console.WriteLine("  -driveletter <N>                    drive letter to mount to");
                    //Console.WriteLine("  -volumeid <VolumeID>                volume ID");
                    //Console.WriteLine("  -plugins name,multiply,parameter    select plugins to load, separate by \"::\"");
                    //Console.WriteLine("                                      uses \"diskspace,100,0\" if omitted");
                    //Console.WriteLine("");
                    //Console.WriteLine("  -logfile none|console|<filename>    specify log file (default: console)");
                    //Console.WriteLine("  -loglevel debug|verbose|info|error|none     select log verbosity (default: info)");
                    //Console.WriteLine("");
                    //Console.WriteLine("  -sample <filename>                  create sample service configuration file");
                    //Console.WriteLine("  -install-service                    install service on the system");
                    //Console.WriteLine("  -remove-service                     remove the service from the system");
                    //Console.WriteLine("  -debug-service                      run server config (config.xml) in console");
                    //Console.WriteLine("                                      forces logfile=console, loglevel=debug");
                    //Console.WriteLine("");
                    //Console.WriteLine("  -version                            show version information");
                    Console.WriteLine("Usage: WinMergeFS <parameters>\n\nParameters:\n\n  -manual\n        manual mount, expects -roots or -rroots and -driveletter\n\n  -profile <filename.xml>\n        mount the specified profile\n\n  -create-profile <filename.xml>\n        create a profile, -roots, -driveletter ...\n\n  -roots <root1>[::<root2>::...]\n        roots, separate by \"::\"\n\n  -rroots <root1>[::<root2>::...]\n        like -roots, but read only\n\n  -driveletter <N>\n        drive letter to mount to\n\n  -volumeid <VolumeID>\n         volume ID\n\n  -plugins name,multiply,parameter[::name,multiply,parameter::...]\n         select plugins to load, separate by \"::\"\n         uses \"diskspace,100,0\" if omitted\n\n  -logfile none|console|<filename>\n         specify log file (default: console)\n\n  -loglevel debug|info|error|none\n         select log verbosity (default: info)\n\n  -sample <filename>\n         create sample service configuration file\n\n  -install-service\n         install service on the system\n\n  -remove-service\n         remove the service from the system\n\n  -debug-service\n         run service config (config.xml) in console\n         forces logfile=console, loglevel=debug\n\n  -version\n         show version information");
                    return;
                }



                // ctrl-trapping stuff, we only come here if a mount is in progress!
                // this means every other if/elseif branch should have a return; at the end
                while (true)
                {
                    cki = Console.ReadKey(true);

                    // give the user the oportunity to press ENTER in order add empty lines in the console window to simplify debugging
                    if (cki.Key == ConsoleKey.Enter)
                    {
                        Console.WriteLine("");
                    }
                    if (((cki.Modifiers & ConsoleModifiers.Control) != 0) & (cki.Key == ConsoleKey.C))
                    {
                        Console.Error.WriteLine("CTRL-C trapped. Shutting down...");
                        if (mounter != null) mounter.unmountAll();
                        return;
                    }

                }
            }

            // this is the case when the application is started as a service

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new WMFSsvc()
            };
            ServiceBase.Run(ServicesToRun);

        }



        public static void CreateSampleConfig(string filename)
        {
            DataSet x = Mounter.GetDataSet();
            DataRow generalrow = x.Tables["general"].NewRow();
            x.Tables["general"].Rows.Add(generalrow);
            generalrow["logfile"] = "none";
            generalrow["loglevel"] = "debug";


            DataRow profilerow = x.Tables["profiles"].NewRow();
            profilerow["path"] = "c:\\profile1.xml";
            x.Tables["profiles"].Rows.Add(profilerow);

            profilerow = x.Tables["profiles"].NewRow();
            profilerow["path"] = "c:\\profile2.xml";
            x.Tables["profiles"].Rows.Add(profilerow);

            x.WriteXml(filename);

        }


    }
}
